package com.example.demo.service.lmp;

import com.example.demo.model.MessageRankDto;
import com.example.demo.model.User;
import com.example.demo.service.IMessageRankService;
import com.example.demo.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MessageRankServiceImpl implements IMessageRankService {
    //消息排行榜key前缀
    private static final String MESSAGE_RANK_KEY="chat:message_rank";
    @Autowired
    private RedisTemplate<String ,String > redisTemplate;
    @Autowired
    private IUserService userService;

    //记录用户消息总数
    @Override
    public void addMessageCount(String userId) {
        //incrementScore：增加有序集合中某个成员的分数，如果成员不存在。则添加到有序集合中
        redisTemplate.opsForZSet().incrementScore(MESSAGE_RANK_KEY,userId,1);
    }

    //获得消息排行榜前十条
    @Override
    public List<MessageRankDto> getMessageRankList() {
      //获得前十条消息总数，并且按照总数倒序排序
        List<MessageRankDto> resultList =new ArrayList<>();
        //reverseRangeWithScores：获取有序集合中指定范围内的成员及其分数，并且是按照分数从高到低的顺序返回（即反向排序）
        Set<ZSetOperations.TypedTuple<String>> topUserMessage =redisTemplate.opsForZSet().reverseRangeWithScores(MESSAGE_RANK_KEY,0,0);
        if(topUserMessage ==null){
            //没有消息排行数据信息，返回空数据
            return  resultList;
        }
        //记录返回结果的用户id列表，用户后面批量查询用户姓名
        List<String > userUdList =new ArrayList<>();
        for(ZSetOperations.TypedTuple<String > topUser : topUserMessage){
            Double score = topUser.getScore();
            String userId = topUser.getValue();
            userUdList.add(userId);
        }

        List<User> userList = userService.listUserByUserIds(userUdList);
        //对userList做了一个k/v的map映射，方便后面拿去用户名称
        Map<String ,User> userMap =new HashMap<>();
        for(User user:userList){
            userMap.put(user.getId(),user);
        }

        //组装消息数据列表内容
        for (ZSetOperations.TypedTuple<String> topUser : topUserMessage) {
            Double score = topUser.getScore();
            String userId = topUser.getValue();
            User user = userMap.get(userId);
            MessageRankDto messageRankDto = new MessageRankDto();
            // 如果数据库有这个用户, 获取用户名称, 防止程序异常
            if(user!=null){
                messageRankDto.setName(user.getName());
            }
            messageRankDto.setScore(score);
            messageRankDto.setUserId(userId);
            resultList.add(messageRankDto);
        }
        return resultList;


    }
}
